﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _04.thread
{
    class Program
    {
        //c#中的thread，需要传入的只是方法(有delegate调用)，如果还有参数，那在Thread.Start(object obj)中传入 - 只能有一个参数！
        //Action、Func #BeginInvoke
        //ThreadPool - 这个适合短暂的任务
        //Task - 这是Thread的封装，可以认为一样的用法。但Task还有ContinueWith，可以用一个线程顺序执行多个任务。Task的状态跟其子任务的状态有关。
        //TaskFactory
        static void Main(string[] args)
        {
            //{//1.前台线程
            //    Thread t1 = new Thread(Calc);
            //    t1.Start();//默认是前台线程，main线程会等待前台线程完成。
            //}

            //{//2.后台线程
            //    Thread t1 = new Thread(Calc);
            //    t1.Start();//默认是前台线程，main线程会等待前台线程完成。
            //    Console.WriteLine("线程已启动！");
            //    t1.IsBackground = true;//设为后台守护线程 - 主线程不会等待后台线程结束！
            //    Console.WriteLine("线程设为后台线程！");
            //}

            //{//3.Abort线程
            //    Thread t1 = new Thread(Calc);
            //    t1.Start();//默认是前台线程，main线程会等待前台线程完成。

            //    Console.WriteLine("线程已启动！");
            //    Thread.Sleep(1000);
            //    t1.Abort();//100ms后放弃t1
            //    //t1.Start();//ERROR: Abort之后无法再次Start！
            //    Console.WriteLine("线程已Abort！");
            //}


            //{//4.传参
            //    Thread t = new Thread(Sum);
            //    t.Start(123456);//这里传入
            //    //var state = t.ThreadState;//获取线程的状态
            //}

            //{//5.Join 让当前线程WaitSleepJoin，然后让目标线程加入进来 - 等它执行完毕!
            //    var m = Thread.CurrentThread;
            //    var t = new Thread(() =>
            //      {
            //          Console.WriteLine("线程开始.." + Thread.CurrentThread.ThreadState);
            //          Console.WriteLine("MainThreadState:" + m.ThreadState); //看看主线程的状态
            //          Thread.Sleep(3000);
            //          Console.WriteLine("线程结束.." + Thread.CurrentThread.ThreadState);
            //      });
            //    t.Start();
            //    t.Join();
            //    Console.WriteLine("Main。。" + Thread.CurrentThread.ThreadState);//看看Join前后当前语句的执行时间
            //}

            {//6.ThreadPool - 线程池创建的线程都是后台线程 - 最多1023个线程，1000个IO线程
                //适合较短的任务；不能修改前后台；不能修改优先级
                ThreadPool.QueueUserWorkItem(Sum, "1");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "2");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "3");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "4");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "5");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "6");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "7");//往线程池中添加方法
                ThreadPool.QueueUserWorkItem(Sum, "8");//往线程池中添加方法

                Thread.Sleep(2000); //
            }
            Console.ReadKey();
        }



        static void Calc()
        {
            int sum = 0;
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                sum += i;
            }
            Console.WriteLine("sum is {0}", sum);
        }

        //需要多线程运行的方法，其参数类型只能是object，且只能有一个参数！
        static void Sum(object a)
        {
            Console.WriteLine(a);
            Thread.Sleep(10000);
        }
    }
}
